import React from "react";
import axios from "axios";

import TodoAdd from "./components/TodoAdd";
import TodoFooter from "./components/TodoFooter";
import TodoList from "./components/TodoList";

class App extends React.Component {
  /**
   * 初始化数据
   */
  state = {
    todos: [],
  };

  /**
   * 组件挂载完成，调用了接口获取数据
   */
  componentDidMount() {
    // 初始化，调用一次 getData
    this.getData();
  }

  /**
   * 查询数据
   */
  getData = () => {
    // 获取数据 GET http://localhost:5000/todos
    axios
      .get("http://localhost:5000/todos")
      .then((response) => {
        console.log("成功了", response.data);

        // 将数据赋值给 state.todos
        this.setState({
          todos: response.data,
        });
      })
      .catch((error) => {
        console.log("失败了", error);
      });
  };

  /**
   * 添加Todo
   * @param {string} payload ‘打豆豆’
   */
  addTodo = (payload) => {
    console.log("App - addTodo", payload);

    // 调用接口，新增todo POST
    axios
      .post("http://localhost:5000/todos", {
        // id: 不用传递
        text: payload,
        done: false,
      })
      .then((response) => {
        console.log("add 成功", response.data);

        // response.data 返回的是，新增成功的数据
        this.setState((prevState) => {
          return {
            todos: [...prevState.todos, response.data],
            // 下面这个代码的问题要说出来
            //    1. 数组的 push 方法会改变原数组
            //    2. 数组的 push 方法返回值是 push 之后的数组的长度。
            // todos: prevState.todos.push(response.data),
          };
        });
      })
      .catch((error) => {
        console.log("add 失败", error);
      });
  };

  /**
   * 删除Todo
   * @param {*} id 要删除的todo 的id
   */
  delTodo = (id) => {
    console.log("App - delTodo", id);

    // 调用接口，删除todo DELETE
    axios
      .delete(`http://localhost:5000/todos/${id}`)
      .then((response) => {
        console.log("del 成功", response.data);
        // 修改 state.todos
        // 修改state数据时，注意遵循一个原则，就是不要改动到原有的state数据
        this.setState((prevState) => {
          return {
            todos: prevState.todos.filter((todo) => todo.id !== id),
          };
        });
      })
      .catch((error) => {
        console.log("del 失败", error);
      });
  };

  /**
   * 修改Todo
   * @param {*} id id
   * @param {*} done true 或者 false
   */
  changeTodo = (id, done) => {
    // console.log("App - change", id, done);
    // 调用接口 PUT-替换 PATCH-局部修改
    axios
      .patch(`http://localhost:5000/todos/${id}`, {
        done: done,
      })
      .then((response) => {
        console.log("change 成功了", response.data);

        // 修改完之后，我们直接重新请求下查询接口，页面是不是就会更新呀。
        this.getData();
      })
      .catch((error) => {
        console.log("change 失败了", error);
      });

    // 先不调用接口，直接修改 state.todos 如何写
    // this.setState((prevState) => {
    //   return {
    //     todos: prevState.todos.map((todo) => {
    //       if (todo.id === id) {
    //         // todo.done = done, 改动了原始数据
    //         // todo.done = done;
    //         return {
    //           ...todo,
    //           done: done,
    //         };
    //       } else {
    //         return todo;
    //       }
    //     }),
    //   };
    // });
  };

  render() {
    const { todos } = this.state;
    const todos_done = todos.filter((item) => item.done);
    const todos_undone = todos.filter((item) => !item.done);

    return (
      <div className="todo">
        <TodoAdd add={this.addTodo} />

        {/* 
          过滤 state.todos 中 done 为 false 的数据传递
        */}
        <TodoList
          title="进行中"
          todos={todos_undone}
          del={this.delTodo}
          change={this.changeTodo}
        />

        {/* 
          过滤 state.todos 中 done 为 true 的数据传递
        */}
        <TodoList
          title="已完成"
          todos={todos_done}
          del={this.delTodo}
          change={this.changeTodo}
        />

        <TodoFooter todos={todos} />
      </div>
    );
  }
}

export default App;
